<!doctype html>
<html>
    <head>
        <title>电信扩展手册 - HT for Web</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="user-scalable=yes, width=1024">
        <style type="text/css">
            h1, h2, h3, h4, h5, h6, p, blockquote {
                margin: 0;
                padding: 0;
            }
            body {
                font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", Arial, sans-serif;
                font-size: 13px;
                line-height: 18px;
                color: #737373;
                background-color: white;
                margin: 10px 13px 10px 13px;
            }
            table {
                margin: 10px 0 15px 0;
                border-collapse: collapse;
            }
            td,th {
                border: 1px solid #ddd;
                padding: 3px 10px;
            }
            th {
                padding: 5px 10px;
            }
            a {
                color: #0069d6;
            }
            a:hover {
                color: #0050a3;
                text-decoration: none;
            }
            a img {
                border: none;
            }
            p {
                margin-bottom: 9px;
            }
            h1, h2, h3, h4, h5, h6 {
                color: #404040;
                line-height: 36px;
            }
            h1 {
                margin-bottom: 18px;
                font-size: 30px;
            }
            h2 {
                font-size: 24px;
            }
            h3 {
                font-size: 18px;
            }
            h4 {
                font-size: 16px;
            }
            h5 {
                font-size: 14px;
            }
            h6 {
                font-size: 13px;
            }
            hr {
                margin: 0 0 19px;
                border: 0;
                border-bottom: 1px solid #ccc;
            }
            blockquote {
                padding: 13px 13px 21px 15px;
                margin-bottom: 18px;
                font-family:georgia,serif;
                font-style: italic;
            }
            blockquote:before {
                content:"\201C";
                font-size:40px;
                margin-left:-10px;
                font-family:georgia,serif;
                color:#eee;
            }
            blockquote p {
                font-size: 14px;
                font-weight: 300;
                line-height: 18px;
                margin-bottom: 0;
                font-style: italic;
            }
            code, pre {
                font-family: Monaco, Andale Mono, Courier New, monospace;
            }
            code {
                background-color: #fee9cc;
                color: rgba(0, 0, 0, 0.75);
                padding: 1px 3px;
                font-size: 12px;
                -webkit-border-radius: 3px;
                -moz-border-radius: 3px;
                border-radius: 3px;
            }
            pre {
                display: block;
                padding: 14px;
                margin: 0 0 18px;
                line-height: 16px;
                font-size: 11px;
                border: 1px solid #d9d9d9;
                white-space: pre-wrap;
                word-wrap: break-word;
            }
            pre code {
                background-color: #fff;
                color:#737373;
                font-size: 11px;
                padding: 0;
            }
            sup {
                font-size: 0.83em;
                vertical-align: super;
                line-height: 0;
            }
            * {
                -webkit-print-color-adjust: exact;
            }
            @media screen and (min-width: 914px) {
                body {
                    width: 854px;
                    margin:10px auto;
                }
            }
            @media print {
                body,code,pre code,h1,h2,h3,h4,h5,h6 {
                    color: black;
                }
                table, pre {
                    page-break-inside: avoid;
                }
            }
            iframe{
                width: 100%;
                border: 1px solid #34495E;
                margin: 0;
            }
            .logo{
                vertical-align: middle;
            }

        </style>
        <script>
            function init() {
                var logoSrc = '',
                    logos = document.querySelectorAll('.logo'),
                    i = 0;
                for (; i < logos.length; i++) {
                    logos[i].src = logoSrc;
                }

                var iframes = document.querySelectorAll('iframe'),
                    func = function(){};
                for (i=0; i < iframes.length; i++) {
                    var iframe = iframes[i];

                    // a small hack to make it work on android
                    iframe.ontouchstart = func;

                    if (window.location && window.location.hostname && window.location.hostname.indexOf('hightopo') >= 0) {
                        var div = document.createElement('div');
                        div.style.float = 'left';
                        div.innerHTML = '<a href="https://hightopo.com/codeeditor/index.html?url=' + iframe.contentWindow.location.pathname + '" target="_blank">在线编辑</a>';
                        iframe.parentNode.insertBefore(div, iframe);

                        var div = document.createElement('div');
                        div.style.float = 'left';
                        div.innerHTML = '&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;';
                        iframe.parentNode.insertBefore(div, iframe);
                    }

                    var div = document.createElement('div');
                    div.innerHTML = '<a href="' + iframe.src + '" target="_blank">独立运行→</a>';
                    iframe.parentNode.insertBefore(div, iframe);
                }
            }
        </script>
    </head>
    <body onload="init();">
        <a href="http://www.hightopo.com"><img class="logo"></a>HT for Web 电信扩展手册
        <hr style="margin: 1px 0 20px 0">
<p>索引</p>

<ul><li><a href="#ref_alarm">告警</a><ul><li><a href="#ref_alarmSeverity">告警级别</a><ul><li><a href="#ref_alarmSeverityDefault">默认告警级别</a></li><li><a href="#ref_alarmSeverityCustom">自定义告警级别</a></li></ul></li><li><a href="#ref_alarmState">告警状态</a><ul><li><a href="#ref_alarmStateOperation">操作</a></li><li><a href="#ref_alarmStateLookup">查询</a></li></ul></li><li><a href="#ref_alarmStatePropagator">告警传播</a><ul><li><a href="#ref_alarmStatePropagatorCustom">自定义告警传播</a></li></ul></li><li><a href="#ref_alarmStateStatistics">告警统计</a><ul><li><a href="#ref_alarmStateStatisticsCustom">自定义告警统计面板</a></li></ul></li><li><a href="#ref_alarmOnTree">告警在树上的展示</a></li></ul></li></ul>

<hr/>

<div id="ref_alarm"></div>

<h2>告警</h2>

<p>告警用于描述电信网管中网元的异常和错误信息。<code>HT</code>中网元有告警状态属性（<code>ht.Data#getAlarmState()</code>，类型为<code>ht.AlarmState</code>），
用于描述网元的告警信息。告警状态中记录了新发告警和确认告警对应于每一种告警级别（<code>ht.AlarmSeverity</code>）的告警数量。</p>

<div id="ref_alarmSeverity"></div>

<h3>告警级别</h3>

<p>告警级别（<code>ht.AlarmSeverity</code>）用于描述告警的严重程度，具有如下属性：</p>

<ul><li><code>value</code> 值（<code>number</code>），用于排序告警级别</li><li><code>name</code> 名称（<code>string</code>），用于唯一标识告警级别</li><li><code>nickName</code> 别名，一般是一个字符，用于告警冒泡上显示简短的告警级别名称</li><li><code>color</code> 颜色（<code>color</code>），用于告警冒泡的背景填充色</li><li><code>displayName</code> 显示名称（<code>string</code>），用于详细描述告警级别</li></ul>

<div id="ref_alarmSeverityDefault"></div>

<h4>默认告警级别</h4>

<p><code>HT</code>预定义了如下告警级别：</p>

<ul><li><code>AlarmSeverity.CRITICAL</code>，严重告警：<code>{value: 500, name: &#39;Critical&#39;, nickName: &#39;C&#39;, color: &#39;#FF0000&#39;}</code></li><li><code>AlarmSeverity.MAJOR</code>，主要告警：<code>{value: 400, name: &#39;Major&#39;, nickName: &#39;M&#39;, color: &#39;#FFA000&#39;}</code></li><li><code>AlarmSeverity.MINOR</code>，次要告警：<code>{value: 300, name: &#39;Minor&#39;, nickName: &#39;m&#39;, color: &#39;#FFFF00&#39;}</code></li><li><code>AlarmSeverity.WARNING</code>，警告告警：<code>{value: 200, name: &#39;Warning&#39;, nickName: &#39;W&#39;, color: &#39;#00FFFF&#39;}</code></li><li><code>AlarmSeverity.INDETERMINATE</code>，未知告警：<code>{value: 100, name: &#39;Indeterminate&#39;, nickName: &#39;N&#39;, color: &#39;#C800FF&#39;}</code></li><li><code>AlarmSeverity.CLEARED</code>，已清除告警：<code>{value: 0, name: &#39;Cleared&#39;, nickName: &#39;R&#39;, color: &#39;#00FF00&#39;}</code></li></ul>

<div id="ref_alarmSeverityCustom"></div>

<h4>自定义告警级别</h4>

<p>除了<code>HT</code>提供的默认告警级别，可以用如下方法添加自定义告警级别：</p>

<h5><code>AlarmSeverity.add(value, name, nickName, color, displayName)</code></h5>

<ul><li><code>value</code> 值（<code>number</code>），用于排序告警级别</li><li><code>name</code> 名称（<code>string</code>），用于唯一标识告警级别</li><li><code>nickName</code> 别名，一般是一个字符，用于告警冒泡上显示简短的告警级别名称</li><li><code>color</code> 颜色（<code>color</code>），用于告警冒泡的背景填充色</li><li><code>displayName</code> 显示名称（<code>string</code>），用于详细描述告警级别</li><li>return <code>ht.AlarmSeverity</code></li></ul>

<p>示例：</p>

<p><iframe src="examples/example_severity.html" style="height:200px"></iframe></p>

<pre><code>var trivial = ht.AlarmSeverity.add(50, &#39;Trivial&#39;, &#39;T&#39;, &#39;#20B2AA&#39;);
console.assert(trivial === ht.AlarmSeverity.getByName(&#39;Trivial&#39;),
	&quot;trivial === ht.AlarmSeverity.getByName(&#39;Trivial&#39;)&quot;);</code></pre>

<p>另外，<code>ht.AlarmSeverity</code>提供了如下Class方法和属性：</p>

<h5><code>AlarmSeverity.severities</code></h5>

<ul><li><code>ht.List</code> 默认和自定义的告警级别都被添加到了这个集合中，其中元素的顺序是按告警级别的<code>value</code>从小到大排序的</li></ul>

<h5><code>AlarmSeverity.each(callbackFunction, [scope])</code></h5>

<ul><li><code>callbackFunction</code> <code>function</code> 回调函数</li><li><code>scope</code> <code>object</code> 回调函数里this指向的对象</li></ul>

<p>循环所有告警级别，执行指定函数</p>

<h5><code>AlarmSeverity.getSortFunction()</code></h5>

<ul><li>return <code>function</code> 排序函数</li></ul>

<p>返回<code>AlarmSeverity.setSortFunction(sortFunction)</code>设置的告警级别排序函数，如果未设置，则返回默认的告警级别排序函数（按告警级别的<code>value</code>从小到大排序）</p>

<h5><code>AlarmSeverity.setSortFunction(sortFunction)</code></h5>

<ul><li><code>sortFunction</code> <code>function</code> 排序函数</li></ul>

<p>设置告警级别排序函数</p>

<h5><code>AlarmSeverity.remove(name)</code></h5>

<ul><li><code>name</code> <code>string</code> 名称</li></ul>

<p>按名称删除指定的告警级别</p>

<h5><code>AlarmSeverity.isClearedAlarmSeverity(severity)</code></h5>

<ul><li><code>severity</code> <code>ht.AlarmSeverity</code> 告警级别</li><li>return <code>boolean</code> 如果指定的告警级别<code>value</code>是<code>0</code>则返回<code>true</code>，否则返回<code>false</code></li></ul>

<h5><code>AlarmSeverity.getByName(name)</code></h5>

<ul><li><code>name</code> <code>string</code> 名称</li><li>return <code>ht.AlarmSeverity</code> 按名字查找告警级别</li></ul>

<h5><code>AlarmSeverity.getByValue(value)</code></h5>

<ul><li><code>value</code> <code>number</code> 值</li><li>return <code>ht.AlarmSeverity</code> 按值查找告警级别</li></ul>

<h5><code>AlarmSeverity.clear()</code></h5>

<p>清空所有告警级别</p>

<h5><code>AlarmSeverity.compare(severity1, severity2)</code></h5>

<ul><li><code>severity1</code> <code>ht.AlarmSeverity</code> 告警级别<code>1</code></li><li><code>severity1</code> <code>ht.AlarmSeverity</code> 告警级别<code>2</code></li><li>return <code>number</code> 如果<code>severity1</code>大于<code>severity2</code>则返回<code>1</code>，如果<code>severity1</code>小于<code>severity2</code>则返回<code>-1</code>，如果<code>severity1</code>等于<code>severity2</code>则返回<code>0</code></li></ul>

<p>比较指定的两个告警级别</p>

<div id="ref_alarmState"></div>

<h3>告警状态</h3>

<p>告警状态（<code>ht.AlarmState</code>）是<code>HT</code>中网元的属性（<code>Data#getAlarmState()</code>）。告警分新发告警（<code>New Alarm</code>）和确认告警（<code>Acknowledged Alarm</code>），
告警状态中记录了新发告警和确认告警对应于每一种告警级别（<code>ht.AlarmSeverity</code>）的告警数量。此外，告警状态还记录了传播告警级别（传播告警指网元所有孩子的最高告警级别）。</p>

<p>如果有新发告警，<code>GraphView</code>上样式<code>note2</code>被替换成新发告警信息，填充色为最高新发告警级别的颜色，文字为最高新发告警级别的数量和别名：</p>

<pre><code>ht.GraphView.prototype.getNote2 = function (data) {
	var severity = data.getAlarmState().getHighestNewAlarmSeverity();
	if (severity) {
		var label = data.getAlarmState().getNewAlarmCount(severity) + severity.nickName;
		if (data.getAlarmState().hasLessSevereNewAlarms()) {
			label += &quot;+&quot;;
		}
		return label;
	}
	return data.getStyle(&#39;note2&#39;);
};
ht.GraphView.prototype.getNote2Background = function (data) {
    var severity = data.getAlarmState().getHighestNewAlarmSeverity();
    if (severity) {
        return severity.color;
    }
    return data.getStyle(&#39;note2.background&#39;);
};</code></pre>

<p>如果有确认告警，网元的填充色变为最高新发或确认告警级别的颜色：</p>

<pre><code>ht.GraphView.prototype.getBodyColor = function (data) {
	var severity = data.getAlarmState().getHighestNativeAlarmSeverity();
	if (severity) {
		return severity.color;
	}
	return data.getStyle(&#39;body.color&#39;);
};</code></pre>

<p>如果有传播告警，网元的边框颜色变为传播告警的颜色：</p>

<pre><code>ht.GraphView.prototype.getBorderColor = function (data) {
	var severity = data.getAlarmState().getPropagateSeverity();
	if (severity) {
		return severity.color;
	}
	return data.getStyle(&#39;border.color&#39;);
};</code></pre>

<p>示例：</p>

<p><iframe src="examples/example_state.html" style="height:200px"></iframe></p>

<div id="ref_alarmStateOperation"></div>

<h4>操作</h4>

<h5><code>AlarmState#increaseNewAlarm(severity, [increment])</code></h5>

<ul><li><code>severity</code> <code>ht.AlarmSeverity</code> 告警级别</li><li><code>increment</code> <code>number</code> 数量，可选，默认值为<code>1</code></li></ul>

<p>增加指定数量和级别的新发告警</p>

<h5><code>AlarmState#decreaseNewAlarm(severity, [decrement])</code></h5>

<ul><li><code>severity</code> <code>ht.AlarmSeverity</code> 告警级别</li><li><code>decrement</code> <code>number</code> 数量，可选，默认值为<code>1</code></li></ul>

<p>减少指定数量和级别的新发告警</p>

<h5><code>AlarmState#setNewAlarmCount(severity, count)</code></h5>

<ul><li><code>severity</code> <code>ht.AlarmSeverity</code> 告警级别</li><li><code>count</code> <code>number</code> 数量</li></ul>

<p>设置指定级别的新发告警数量</p>

<h5><code>AlarmState#removeAllNewAlarms(severity)</code></h5>

<ul><li><code>severity</code> <code>ht.AlarmSeverity</code> 告警级别</li></ul>

<p>清除所有新发告警</p>

<h5><code>AlarmState#acknowledgeAlarm(severity)</code></h5>

<ul><li><code>severity</code> <code>ht.AlarmSeverity</code> 告警级别</li></ul>

<p>确认一条指定级别的新发告警</p>

<h5><code>AlarmState#acknowledgeAllAlarms([severity])</code></h5>

<ul><li><code>severity</code> <code>ht.AlarmSeverity</code> 告警级别，可选</li></ul>

<p>确认指定级别的所有新发告警，如果<code>severity</code>参数省略，则确认所有级别的新发告警</p>

<h5><code>AlarmState#increaseAcknowledgedAlarm(severity, [increment])</code></h5>

<ul><li><code>severity</code> <code>ht.AlarmSeverity</code> 告警级别</li><li><code>increment</code> <code>number</code> 数量，可选，默认值为<code>1</code></li></ul>

<p>增加指定数量和级别的确认告警</p>

<h5><code>AlarmState#decreaseAcknowledgedAlarm(severity, [decrement])</code></h5>

<ul><li><code>severity</code> <code>ht.AlarmSeverity</code> 告警级别</li><li><code>decrement</code> <code>number</code> 数量，可选，默认值为<code>1</code></li></ul>

<p>减少指定数量和级别的确认告警</p>

<h5><code>AlarmState#setAcknowledgedAlarmCount(severity, count)</code></h5>

<ul><li><code>severity</code> <code>ht.AlarmSeverity</code> 告警级别</li><li><code>count</code> <code>number</code> 数量</li></ul>

<p>设置指定级别的确认告警数量</p>

<h5><code>AlarmState#removeAllAcknowledgedAlarms(severity)</code></h5>

<ul><li><code>severity</code> <code>ht.AlarmSeverity</code> 告警级别</li></ul>

<p>清除所有确认告警</p>

<h5><code>AlarmState#clear()</code></h5>

<p>清除所有新发和确认告警</p>

<h5><code>AlarmState#setPropagateSeverity(severity)</code></h5>

<ul><li><code>severity</code> <code>ht.AlarmSeverity</code> 告警级别</li></ul>

<p>设置传播告警级别</p>

<h5><code>AlarmState#setEnablePropagation(value)</code></h5>

<ul><li><code>value</code> <code>boolean</code> 否启用告警传播</li></ul>

<p>设置是否启用告警传播，默认值为<code>true</code></p>

<div id="ref_alarmStateLookup"></div>

<h4>查询</h4>

<h5><code>AlarmState#getHighestAcknowledgedAlarmSeverity()</code></h5>

<ul><li>return <code>ht.AlarmSeverity</code> 返回最高的确认告警级别</li></ul>

<h5><code>AlarmState#getHighestNewAlarmSeverity()</code></h5>

<ul><li>return <code>ht.AlarmSeverity</code> 返回最高的新发告警级别</li></ul>

<h5><code>AlarmState#getHighestNativeAlarmSeverity()</code></h5>

<ul><li>return <code>ht.AlarmSeverity</code> 返回最高的确认或新发告警级别</li></ul>

<h5><code>AlarmState#getPropagateSeverity()</code></h5>

<ul><li>return <code>ht.AlarmSeverity</code> 返回传播告警级别</li></ul>

<h5><code>AlarmState#getHighestOverallAlarmSeverity()</code></h5>

<ul><li>return <code>ht.AlarmSeverity</code> 返回最高的确认、新发或传播告警级别</li></ul>

<h5><code>AlarmState#hasLessSevereNewAlarms()</code></h5>

<ul><li>return <code>boolean</code> 返回是否有低于最高新发告警级别的新发告警</li></ul>

<h5><code>AlarmState#getNewAlarmCount(severity)</code></h5>

<ul><li><code>severity</code> <code>ht.AlarmSeverity</code> 告警级别</li><li>return <code>number</code> 返回指定告警级别的新发告警数量</li></ul>

<h5><code>AlarmState#getAcknowledgedAlarmCount(severity)</code></h5>

<ul><li><code>severity</code> <code>ht.AlarmSeverity</code> 告警级别</li><li>return <code>number</code> 返回指定告警级别的确认告警数量</li></ul>

<h5><code>AlarmState#getAlarmCount(severity)</code></h5>

<ul><li><code>severity</code> <code>ht.AlarmSeverity</code> 告警级别</li><li>return <code>number</code> 返回指定告警级别的确认和新发告警数量总和</li></ul>

<h5><code>AlarmState#isEmpty()</code></h5>

<ul><li>return <code>boolean</code> 返回是否没有新发、确认或传播告警</li></ul>

<h5><code>AlarmState#isEnablePropagation()</code></h5>

<ul><li>return <code>boolean</code> 返回是否启用告警传播，默认值为<code>true</code></li></ul>

<div id="ref_alarmStatePropagator"></div>

<h3>告警传播</h3>

<p>在<code>HT</code>中，告警传播<code>ht.AlarmStatePropagator</code>会将底层网元的告警往上层网元传播，比如<code>Group</code>或<code>SubGraph</code>中所有孩子的最高级别告警会传播到<code>Group</code>或<code>SubGraph</code>。
默认告警传播未开启，需要调用<code>ht.DataModel#setEnableAlarmStatePropagator(true)</code>开启告警传播。</p>

<div id="ref_alarmStatePropagatorCustom"></div>

<h4>自定义告警传播</h4>

<p>默认告警传播是从孩子传播到父亲，可以重写<code>ht.AlarmStatePropagator</code>的<code>propagateToTop</code>方法改变传播机制，下面例子演示了告警沿着<code>host</code>传播：</p>

<p>先关闭数据容器的告警传播（<code>ht.DataModel#setEnableAlarmStatePropagator(false)</code>）,然后创建新的<code>ht.AlarmStatePropagator</code>对象，再重写
<code>AlarmStatePropagator#handleDataPropertyChange(e)</code>和<code>AlarmStatePropagator#propagateToTop(data)</code>方法：</p>

<pre><code>propagator.handleDataPropertyChange = function (e) {
	ht.AlarmStatePropagator.prototype.handleDataPropertyChange.call(this, e);
	if (e.property === &#39;host&#39;) {
    	var oldHost = e.oldValue;
		if (oldHost) {
			this.propagate(oldHost);
		}
		this.propagate(e.data);
	}
};
propagator.propagateToTop = function (data) {
	this.propagateToHost(null, data);
	while (data &amp;&amp; data.getHost()) {
		this.propagateToHost(data, data.getHost());
		data = data.getHost();
	}
};
propagator.propagateToHost = function (attach, host) {
	var result = null;
	if (host.getAttaches()) {
		host.getAttaches().each(function (attach) {
			var severity = attach.getAlarmState().getHighestOverallAlarmSeverity();
			if (ht.AlarmSeverity.compare(severity, result) &gt; 0) {
				result = severity;
			}
			});
		}
		host.getAlarmState().setPropagateSeverity(result);
	};</code></pre>

<p><iframe src="examples/example_propagator.html" style="height:200px"></iframe></p>

<p><code>AlarmStatePropagator</code>包含如下方法：</p>

<h5><code>AlarmStatePropagator(dataModel)</code></h5>

<ul><li><code>dataModel</code> <code>ht.DataModel</code> 数据容器</li></ul>

<p>构造函数，构建告警传播</p>

<h5><code>AlarmStatePropagator#getDataModel()</code></h5>

<ul><li>return <code>ht.DataModel</code> 返回关联的数据容器</li></ul>

<h5><code>AlarmStatePropagator#isEnable()</code></h5>

<ul><li>return <code>boolean</code> 返回是否启用告警传播，默认为<code>false</code></li></ul>

<h5><code>AlarmStatePropagator#setEnable(enable)</code></h5>

<ul><li><code>enable</code> <code>boolean</code> 是否启用告警传播</li></ul>

<p>设置是否启用告警传播</p>

<h5><code>AlarmStatePropagator#handleDataModelChange(e)</code></h5>

<ul><li><code>e</code> <code>object</code> 模型更改事件，包含如下属性：<ul><li><code>kind</code> <code>string</code> 取值为<code>add</code>, <code>remove</code>, <code>clear</code></li><li><code>data</code> <code>ht.Data</code> 当<code>kind</code>为<code>add</code>或<code>remove</code>时，<code>data</code>属性为添加或删除的数据，当<code>kind</code>为<code>clear</code>时，<code>data</code>属性为<code>null</code></li></ul></li></ul>

<p>数据容器更改回调函数，处理告警传播</p>

<h5><code>AlarmStatePropagator#handleDataPropertyChange(e)</code></h5>

<ul><li><code>e</code> <code>object</code> 数据更改事件，包含如下属性：<ul><li><code>property</code> <code>string</code> 发生变化的属性</li><li><code>oldValue</code> <code>object</code> 旧值</li><li><code>newValue</code> <code>object</code> 新值</li><li><code>data</code> <code>ht.Data</code> 发生属性变化的数据</li></ul></li></ul>

<p>数据属性更改回调函数，处理告警传播</p>

<h5><code>AlarmStatePropagator#propagate(data)</code></h5>

<ul><li><code>data</code> <code>ht.Data</code> 数据</li></ul>

<p>传播告警</p>

<h5><code>AlarmStatePropagator#propagateToTop(data)</code></h5>

<ul><li><code>data</code> <code>ht.Data</code> 数据</li></ul>

<p>传播告警到上层</p>

<h5><code>AlarmStatePropagator#propagateToParent(data)</code></h5>

<ul><li><code>data</code> <code>ht.Data</code> 数据</li></ul>

<p>传播告警到父亲</p>

<div id="ref_alarmStateStatistics"></div>

<h3>告警统计</h3>

<p>告警统计（<code>ht.AlarmStateStatistics</code>）用于统计数据容器中所有数据的各告警级别的新发、确认以及总数量。</p>

<h5><code>AlarmStateStatistics(dataModel)</code></h5>

<ul><li><code>dataModel</code> <code>ht.DataModel</code> 数据容器</li></ul>

<p>构造函数，创建告警统计对象</p>

<h5><code>AlarmStateStatistics#getDataModel()</code></h5>

<ul><li>return <code>ht.DataModel</code> 返回关联的数据容器</li></ul>

<h5><code>AlarmStateStatistics#setDataModel(dataModel)</code></h5>

<ul><li><code>dataModel</code> <code>ht.DataModel</code> 设置关联的数据容器</li></ul>

<h5><code>AlarmStatePropagator#dispose()</code></h5>

<p>销毁告警统计，删除对数据容器和数据的监听</p>

<h5><code>AlarmStateStatistics#handleDataModelChange(e)</code></h5>

<ul><li><code>e</code> <code>object</code> 模型更改事件，包含如下属性：<ul><li><code>kind</code> <code>string</code> 取值为<code>add</code>, <code>remove</code>, `clear</li><li><code>data</code> <code>ht.Data</code> 当<code>kind</code>为<code>add</code>或<code>remove</code>时，<code>data</code>属性为添加或删除的数据，当<code>kind</code>为<code>clear</code>时，<code>data</code>属性为<code>null</code></li></ul></li></ul>

<p>数据容器更改回调函数，重新统计告警数量</p>

<h5><code>AlarmStateStatistics#handleDataPropertyChange(e)</code></h5>

<ul><li><code>e</code> <code>object</code> 数据更改事件，包含如下属性：<ul><li><code>property</code> <code>string</code> 发生变化的属性</li><li><code>oldValue</code> <code>object</code> 旧值</li><li><code>newValue</code> <code>object</code> 新值</li><li><code>data</code> <code>ht.Data</code> 发生属性变化的数据</li></ul></li></ul>

<p>数据属性更改回调函数，重新统计告警数量</p>

<h5><code>AlarmStateStatistics#fireAlarmStateChange()</code></h5>

<p>重新统计告警数量，派发<code>alarmState</code>更改事件</p>

<h5><code>AlarmStateStatistics#getNewAlarmCount([severity])</code></h5>

<ul><li><code>severity</code> <code>ht.AlarmSeverity</code> 告警级别，可选</li><li>return <code>number</code> 返回指定告警级别的统计新发告警数量，如果不提供<code>severity</code>参数，则返回所有级别的新发告警数</li></ul>

<h5><code>AlarmStateStatistics#getAcknowledgedAlarmCount([severity])</code></h5>

<ul><li><code>severity</code> <code>ht.AlarmSeverity</code> 告警级别，可选</li><li>return <code>number</code> 返回指定告警级别的统计确认告警数量，如果不提供<code>severity</code>参数，则返回所有级别的确认告警数</li></ul>

<h5><code>AlarmStateStatistics#getTotalAlarmCount([severity])</code></h5>

<ul><li><code>severity</code> <code>ht.AlarmSeverity</code> 告警级别，可选</li><li>return <code>number</code> 返回指定告警级别的统计新发和确认告警数量，如果不提供<code>severity</code>参数，则返回所有级别的新发和确认告警数</li></ul>

<h5><code>AlarmStateStatistics#getSumInfo(severity)</code></h5>

<ul><li><code>severity</code> <code>ht.AlarmSeverity</code> 告警级别</li><li>return <code>object</code> 返回指定告警级别的统计新发、确认以及新发和确认告警数量<ul><li><code>newCount</code> <code>number</code> 新发告警数量</li><li><code>ackedCount</code> <code>number</code> 确认告警数量</li><li><code>totalCount</code> <code>number</code> 新发和确认告警数量</li></ul></li></ul>

<h5><code>AlarmStateStatistics#increase(data)</code></h5>

<ul><li><code>data</code> <code>ht.Data</code> 数据</li></ul>

<p>增加指定数据的告警</p>

<h5><code>AlarmStateStatistics#decrease(data)</code></h5>

<ul><li><code>data</code> <code>ht.Data</code> 数据</li></ul>

<p>减少指定数据的告警</p>

<h5><code>AlarmStateStatistics#reset()</code></h5>

<p>重新统计告警数量</p>

<h5><code>AlarmStateStatistics#getFilterFunc()</code></h5>

<ul><li>return <code>function</code> 返回过滤函数<ul><li><code>data</code> <code>ht.Data</code> 数据</li><li>return <code>boolean</code> 返回<code>true</code>则不统计此数据的告警信息，否则参与统计</li></ul></li></ul>

<h5><code>AlarmStateStatistics#setFilterFunc(value)</code></h5>

<ul><li><code>value</code> <code>function</code> 过滤函数<ul><li><code>data</code> <code>ht.Data</code> 数据</li><li>return <code>boolean</code> 返回<code>true</code>则不统计此数据的告警信息，否则参与统计</li></ul></li></ul>

<p>设置过滤函数，过滤不参与统计的数据</p>

<div id="ref_alarmStateStatisticsCustom"></div>

<h4>自定义告警统计面板</h4>

<p>下面的例子演示了用矢量实现告警统计面板：</p>

<p><iframe src="examples/example_statistics.html" style="height:200px"></iframe></p>

<div id="ref_alarmOnTree"></div>

<h2>告警在树上的展示</h2>

<p>默认树上节点的图标填充色是数据的最高新发或确认告警级别的颜色，如果有传播告警，树节点图标会加上颜色为传播告警级别颜色的边框：</p>

<pre><code>ht.widget.TreeView.prototype.getIcon = ht.widget.TreeTableView.prototype.getIcon = function (data) {
	return &#39;__alarmIcon__&#39;;
};
ht.Default.setImage(&#39;__alarmIcon__&#39;, {
    width: 18,
    height: 18,
    comps: [
        {
            type: &#39;image&#39;,
            name: {
                func: function (data) { return data.getIcon(); }
            },
            color: {
                func: function (data) {
                    var severity = data.getAlarmState().getHighestNativeAlarmSeverity();
                    if (severity) {
                        return severity.color;
                    }
                    return data.getStyle(&#39;body.color&#39;);
                }
            },
            rect: [1, 1, 16, 16]
        },
        {
            type: &#39;rect&#39;,
            borderWidth: 2,
            borderColor: {
                func: function (data) {
                    var severity = data.getAlarmState().getPropagateSeverity();
                    if (severity) {
                        return severity.color;
                    }
                    return data.getStyle(&#39;border.color&#39;);
                }
            },
            visible: {
                func: function (data) {
                    return !!data.getAlarmState().getPropagateSeverity() || !!data.getStyle(&#39;border.color&#39;);
                },
            },
            rect: [1, 1, 16, 16]
        }
    ]
});</code></pre>

<p>下面的例子在树节点图标的左下角加上了小圆圈，代表最高级别的新发告警：</p>

<p><iframe src="examples/example_tree.html" style="height:200px"></iframe></p>

<pre><code>ht.Default.getImage(&#39;__alarmIcon__&#39;).comps.push({
    type: &#39;circle&#39;,
    gradient: &#39;radial.center&#39;,
    gradientColor: &#39;#FFFFFF&#39;,
    background: {
        func: function (data) {
            var severity = data.getAlarmState().getHighestNewAlarmSeverity();
            if (severity) {
                return severity.color;
            }
            return null;
        }
    },
    visible: {
        func: function (data) {
            return !!data.getAlarmState().getHighestNewAlarmSeverity();
        },
    },
    rect: [1, 8, 8, 8]
});</code></pre>    <hr id="contact" style="margin: 20px 0 1px 0">
    <a href="http://www.hightopo.com"><img class="logo"></a>欢迎交流 <a href="mailto:service@hightopo.com">service@hightopo.com</a>
</body>
</html>
